package com.rfid.reader;

import java.io.IOException;
import com.rfid.transport.Transport;
import com.rfid.transport.TransportSerialPort;
import com.rfid.transport.TransportTcpClient;
import com.rfid.transport.TransportUdp;


public abstract class RfidReader {
	public final static int CONNECT_TYPE_SERIALPORT = 0;
	public final static int CONNECT_TYPE_NET_UDP = 1;
	public final static int CONNECT_TYPE_NET_TCP_CLIENT = 2;
	public final static int CONNECT_TYPE_NET_TCP_SERVER = 3;
	private static final int MAX_RECV_BUFF_SIZE = 1024;
	private static final int MAX_SEND_BUFF_SIZE = 128;

	public static final byte MEMBANK_RESERVE = 0;
	public static final byte MEMBANK_EPC = 1;
	public static final byte MEMBANK_TID = 2;
	public static final byte MEMBANK_USER = 3;


	private String key;
	public byte[] recvMsgBuff;
	public int recvMsgLen;
	private AppNotify appNotify;
	protected byte[] sendMsgBuff;
	protected int sendIndex;
	public int recvLen = 0;
	public Transport transport = null;	//the type of communication with reader
	public int connectType = 0;
	
	public RfidReader() {
		recvMsgBuff = new byte[MAX_RECV_BUFF_SIZE];
		sendMsgBuff = new byte[MAX_SEND_BUFF_SIZE];
	}
	
	public AppNotify getAppNotify() {
		return appNotify;
	}

	public void setAppNotify(AppNotify appNotify) {
		this.appNotify = appNotify;
	}
	
	public String getKey() {
		return key;
	}
	public int ConnectPhysicalInterface(String physicalName,int physicalParam,String localAddrStr,int localAddrPort,int connectType) throws Exception {
		int result = -1;
		this.connectType = connectType;
			
		if (CONNECT_TYPE_NET_TCP_CLIENT == connectType){
			TransportTcpClient tcpTransport = new TransportTcpClient();
			tcpTransport.SetConfig(physicalName, physicalParam, localAddrStr, localAddrPort);
			result = tcpTransport.RequestLocalResource();
			key = "TCP:"+ localAddrStr + ":" + localAddrPort;
			if (result == 0) {
				transport = tcpTransport;
			}
		}
		else if (CONNECT_TYPE_NET_UDP == connectType) {
			TransportUdp udpTransport = new TransportUdp();
			udpTransport.SetConfig(physicalName, physicalParam, localAddrStr, localAddrPort);
			result = udpTransport.RequestLocalResource();
			key = "UDP:"+ localAddrStr + ":" + localAddrPort;
			if ( result == 0) {
				transport = udpTransport;
			}
		}
		else if (CONNECT_TYPE_SERIALPORT == connectType) {
			TransportSerialPort serialPort = new TransportSerialPort();
			serialPort.SetSerialPortConfig(physicalName, physicalParam);
			result = serialPort.RequestLocalResource();
			key = physicalName;
			if (0 == result) {
				transport = serialPort;
			}
		}
		else if (CONNECT_TYPE_NET_TCP_SERVER == connectType) {
			
		}
		return result;
	}
	
	public int getUnsignedByte (byte data){ //��data�ֽ�������ת��Ϊ0~255 (0xFF ��BYTE)�� 
		return data&0x0FF ; 
	}

	public abstract int Inventory() throws IOException;
	public abstract int InventoryOnce() throws IOException;
	public abstract int Stop() throws IOException;
	public abstract int Reset() throws IOException;
	public abstract int RelayControl(int relayNo, int operation,int time) throws IOException;
	public abstract int ReadTagBlock(byte membank,byte addr,byte len,byte[] accessPassword) throws IOException;
	public abstract int WriteTagBlock(byte membank,int addr,byte len, byte[] writtenData,int writeStartIndex,byte[] accessPassword) throws IOException;
	public abstract int LockTag(byte lockType,byte[] accessPassword) throws IOException;
	public abstract int KillTag(byte[] accessPassword,byte[] killPassword) throws IOException;
	
	public abstract int HandleRecv() throws IOException;
	public abstract void HandleMessage();
	protected abstract void NotifyMessageToApp(byte[] message,int startIndex);
	public Transport getTransport() {
		return transport;
	}
}
